package com.iot08.admin.service;

import com.aliyun.tea.utils.StringUtils;
import com.iot08.admin.resp.VipMemberResp;
import com.iot08.admin.service.page.PageVO;
import com.iot08.admin.service.page.PageableImpl;
import com.iot08.admin.vo.VipMemberReqVo;
import com.iot08.common.entity.admin.SysUser;
import com.iot08.common.entity.app.*;
import com.iot08.common.service.base.BaseService;

import com.iot08.common.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * @author cwj
 * @description
 * @date 2024/12/29 9:39
 **/
@Slf4j
@Service
public class VipMemberService extends BaseService<VipMember> {

    @Resource
    private AccountService accountService;

    @Resource
    private OperationService operationService;

    /**
     * @description
     * @author cwj
     * @param [openid]
     * @return com.iot08.common.entity.app.VipMember
     * @date @time 2025/2/19 14:49
     **/
    public VipMember queryVipMemberByOpenId(String openid) {
        return this.findOne(new Query(Criteria.where("openid").is(openid)));
    }


    /**
     * @description
     * @author cwj
     * @param [page, openid, checkCode, status]
     * @return org.springframework.data.domain.Page<com.iot08.common.entity.app.BrokenScreenInsurance>
     * @date @time 2025/4/17 11:51
     **/
    public Page<VipMemberResp> list(PageVO page, String openid, String phone, Integer isVip) {
        int currentPage = page.getCurrentPageParam();
        int pageSize = page.getShowCount();
        //log.info("currentPage-----:{}",currentPage);
        PageableImpl pageable = new PageableImpl();
        //page.setSort(Sort.by(Sort.Order.desc("createTime")));
        pageable.setPage(page);

        // 动态构建匹配条件
        List<Criteria> criteriaList = new ArrayList<>();
        if (!StringUtils.isEmpty(openid)) {
            criteriaList.add(Criteria.where("openid").is(openid));
        }
        if (!ObjectUtils.isEmpty(isVip)) {
            criteriaList.add(Criteria.where("isVip").is(isVip));
        }

        // lookup & unwind 提前做，以便对 accountData 过滤
        LookupOperation lookup = Aggregation.lookup("account", "openid", "_id", "accountData");
        UnwindOperation unwind = Aggregation.unwind("accountData", true);

        // accountData 相关条件
        if (!StringUtils.isEmpty(phone)) {
            criteriaList.add(Criteria.where("accountData.phone").is(phone));
        }

        Criteria matchCriteria = new Criteria();
        if (!criteriaList.isEmpty()) {
            matchCriteria = new Criteria().andOperator(criteriaList.toArray(new Criteria[0]));
        }
        // 总数查询
        Aggregation countAgg = Aggregation.newAggregation(
                lookup,
                unwind,
                Aggregation.match(matchCriteria),
                Aggregation.count().as("totalCount")
        );
        AggregationResults<Document> countResults = mongoTemplate.aggregate(countAgg, "vip_member", Document.class);
        int totalCount = countResults.getMappedResults().isEmpty() ? 0 :
                countResults.getMappedResults().get(0).getInteger("totalCount");

        // 分页查询
        Aggregation agg = Aggregation.newAggregation(
                lookup,
                unwind,
                Aggregation.match(matchCriteria),
                Aggregation.project()
                        .and("_id").as("id")
                        .and("orderid").as("orderid")
                        .and("pId").as("pId")
                        .and("openid").as("openid")
                        .and("grade").as("grade")
                        .and("type").as("type")
                        .and("isAgreeVipProtocol").as("isAgreeVipProtocol")
                        .and("isVip").as("isVip")
                        .and("isOnTrialVip").as("isOnTrialVip")
                        .and("beginTime").as("beginTime")
                        .and("endTime").as("endTime")
                        .and("createTime").as("createTime")
                        .and("accountData.createTime").as("accountCreateTime")
                        .and("updateTime").as("updateTime")
                        .and("accountData.phone").as("phone"),
                Aggregation.sort(Sort.by(Sort.Direction.DESC, "createTime")),
                Aggregation.skip((currentPage-1)*pageSize),
                Aggregation.limit(pageSize)
        );
        List<VipMemberResp> list = mongoTemplate.aggregate(agg, "vip_member", VipMemberResp.class).getMappedResults();
        page.setTotalResult(totalCount);
        page.setCurrentPage(currentPage);
        int totalPage = 1;
        if(totalCount%pageSize==0){
            totalPage =  (totalCount/pageSize);
        }else{
            totalPage =  (totalCount/pageSize) + 1;
        }
        page.setTotalPage(totalPage);
        Page<VipMemberResp> result = new PageImpl<VipMemberResp>(list, pageable, totalCount);
        return result;
    }


    /**
     * @description 查询会员信息
     * @author cwj
     * @param [id]
     * @return com.iot08.admin.resp.VipMemberResp
     * @date @time 2025/4/18 9:21
     **/
    public VipMemberResp queryById(String id) {
        VipMemberResp vipMemberResp = mongoTemplate.findById(new ObjectId(id),VipMemberResp.class,"vip_member");
        if(!ObjectUtils.isEmpty(vipMemberResp)) {
            Account account = accountService.findById(vipMemberResp.getOpenid());
            if(!ObjectUtils.isEmpty(account) && !StringUtils.isEmpty(account.getPhone())) {
                vipMemberResp.setPhone(account.getPhone());
            }
        }
        return vipMemberResp;
    }


    /**
     * @description 更新会员的有效时间
     * @author cwj
     * @param [openid, productType]
     * @return void
     * @date @time 2025/2/18 16:21
     **/
    public void updateVipMemberEffectTimeTypeOrderId(String openid,Integer productType,boolean isDeleteCurrentOrder,String secondOrderId,Integer secondProductType){
         Query query = new Query(Criteria.where("openid").is(openid)).limit(1);
         VipMember vipMember = this.findOne(query);
         if(!ObjectUtils.isEmpty(vipMember)) {
             Update update = new Update();
             Long endTime = vipMember.getEndTime();
             long currentTime = System.currentTimeMillis()/1000;
             //会员更新时间为则将其设置到期时间为昨天
             if(ObjectUtils.isEmpty(endTime)){
                 endTime = currentTime - 24*60*60;
             } else {
                 //会员到期时间减少相应产品类型的时间
                 endTime = cutDownVipEndTime(productType, endTime);
             }
             //删除当前订单且前面仍有有效支付的会员订单，且订单在有效期内
             if(isDeleteCurrentOrder) {
                 if (!StringUtils.isEmpty(secondOrderId)){
                     update.set("orderid",secondOrderId);
                 }
                 if(!ObjectUtils.isEmpty(secondProductType)){
                     update.set("type",secondProductType);
                 }
             }
             update.set("endTime",endTime);
             update.set("updateTime",new Date());
             this.updateById(new ObjectId(vipMember.getId()),update);
         }
    }

    /**
     * @description 削减会员有效时间
     * @author cwj
     * @param [productType, endTime]
     * @return java.lang.Long
     * @date @time 2025/2/18 16:29
     **/
    private Long cutDownVipEndTime(Integer productType, Long endTime) {
        switch(productType){
            case 1:
                endTime = endTime - 30*24*60*60;
                break;
            case 2:
                endTime = endTime - 365*24*60*60;
                break;
            case 3:
                endTime = endTime - 150L*365*24*60*60;
                break;
            default:
                break;
        }
        return endTime;
    }


    /**
     * @description 计算机制日期
     * @author cwj
     * @param [vo, currentTime]
     * @return java.lang.Long
     * @date @time 2024/12/29 16:38
     **/
    private Long transferEndTime(Integer type, long currentTime) {
        long deadline = currentTime+30*24*60*60;
        switch(type){
            case 1:
                deadline = currentTime + 30*24*60*60;
                break;
            case 2:
                deadline = currentTime + 365*24*60*60;
                break;
            case 3:
                deadline = currentTime + 150L*365*24*60*60;
                break;
            case 4:{
                deadline = currentTime + 182*24*60*60;
                break;
            }
            default:
                break;
        }
        return deadline;
    }


    /**
     * @description 更新会员信息
     * @author cwj
     * @param [payOrderInfo, isVip]
     * @return void
     * @date @time 2025/2/26 10:02
     **/
    public void updateVipMemberInfo(PayOrderInfo payOrderInfo, Integer isVip)  {
        Query query;
        Update update = new Update();
        update.set("updateTime",new Date());
        //查询缓存信息
        try {
            log.info("更新会员信息......");
            query = new Query(Criteria.where("openid").is(payOrderInfo.getOpenid())).limit(1);
            long currentTime = System.currentTimeMillis()/1000;
            VipMember vipMember = this.findOne(query);
            //会员信息存在
            if(ObjectUtils.isNotEmpty(vipMember)) {
                long endTime = vipMember.getEndTime();
                //如果是免费会员或最后买的会员已经过期
                if(vipMember.getIsVip().equals(1) && currentTime>=endTime){
                    update.set("orderid",payOrderInfo.getId());
                    update.set("type",payOrderInfo.getProductType());
                    update.set("pId",payOrderInfo.getPId());
                    update.set("grade",1);
                }
                //支付之后，用户就不再是免费会员了
                update.set("isOnTrialVip",0);
                //之前的会员还没结束，则续签会员
                if(vipMember.getIsVip().equals(1) && endTime>currentTime){
                    update.set("endTime",transferEndTime(payOrderInfo.getProductType(),endTime));
                } else {
                    update.set("endTime",transferEndTime(payOrderInfo.getProductType(),currentTime));
                }
                //更新会员信息
                this.updateById(new ObjectId(vipMember.getId()),update);
            } else {
                //会员信息不存在，保存会员信息
                vipMember = buildVipMember(payOrderInfo, isVip, currentTime);
                this.save(vipMember);
            }
        } catch (Exception e){
            log.error("会员更新失败，发生异常，异常信息为：{}",e.getMessage());
        }
    }

    /**
     * @description 构建会员信息
     * @author cwj
     * @param [payOrderInfo, isVip, currentTime]
     * @return com.iot08.common.entity.app.VipMember
     * @date @time 2025/2/26 10:38
     **/
    private VipMember buildVipMember(PayOrderInfo payOrderInfo, Integer isVip, long currentTime) {
        VipMember vipMember = new VipMember();
        vipMember.setOpenid(payOrderInfo.getOpenid());
        vipMember.setOrderid(payOrderInfo.getId());
        vipMember.setPId(payOrderInfo.getPId());
        vipMember.setIsAgreeVipProtocol(1);
        vipMember.setGrade(1);
        vipMember.setBeginTime(currentTime);
        vipMember.setType(payOrderInfo.getProductType());
        vipMember.setEndTime(transferEndTime(payOrderInfo.getProductType(), currentTime));
        vipMember.setIsVip(ObjectUtils.isEmpty(isVip)?0: isVip);
        vipMember.setIsOnTrialVip(0);
        vipMember.setCreateTime(new Date());
        vipMember.setUpdateTime(new Date());
        return vipMember;
    }

    /**
     * @description
     * @author cwj
     * @param [vipMemberReqVo, user, ip]
     * @return void
     * @date @time 2025/4/18 11:13
     **/
    public void updateVipMember(VipMemberReqVo vipMemberReqVo, SysUser user, String ip) {
        VipMember vipMember = this.findById(new ObjectId(vipMemberReqVo.getId()));
        //APP标识不能重复
        if(!ObjectUtils.isEmpty(vipMember)){
            Update update = new Update();
            long beginTime = DateUtil.strToTimestamp(vipMemberReqVo.getBeginTime(),DateUtil.FORMAT_1);
            long endTime = DateUtil.strToTimestamp(vipMemberReqVo.getEndTime(),DateUtil.FORMAT_1);
            update.set("beginTime",beginTime/1000);
            update.set("endTime",endTime/1000);
            update.set("type",vipMemberReqVo.getType());
            update.set("isVip",vipMemberReqVo.getIsVip());
            update.set("isOnTrialVip",0);
            update.set("updateTime", new Date());
            this.updateById(new ObjectId(vipMemberReqVo.getId()), update);
            operationService.add(user, ip, "更新会员信息", "编辑",
                    String.format("修改用户:%s的会员信息:", vipMember.getOpenid()));
        }
    }

}
